/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package pos.Driving.Camera;

import javax.vecmath.Vector3d;
import pos.ControlCenter;
import pos.Driving.Path.PosPoint;
import pos.Driving.Train.Train;
import pos.IModeController;
import pos.utils.Invokeable;

/**
 *
 * @author 郑昊
 */
public class Camera implements Invokeable {

    public final static int STATUE_FOLLOWING = 0,  STATUE_DRIVER = 1,  STATUE_CUSTOMIZE = 3;
    public final static int FOLLOW_DRIVER = 0,  FOLLOW_OUTSIDE = 1,  FOLLOW_CARRIAGE = 2,  FOLLOW_FIXED = 3,FOLLOW_DESK=4;
    private int statue = STATUE_FOLLOWING,  following_type = FOLLOW_DRIVER;
    private IModeController myController;
    private Train target;

    public Camera(IModeController myController) {
        this.myController = myController;
    }

    @Override
    public void invoke(double Step) {
        target = (Train) myController.doEvent("GetTrain", null);
        switch (statue) {
            case Camera.STATUE_FOLLOWING:
                setFollowingCamera();
                break;
            case Camera.STATUE_DRIVER:
                setDriverCamera();
                break;
            case Camera.STATUE_CUSTOMIZE:
                if(!target.getTrainGroup().isLive())
                    ControlCenter.objRoot.addChild(target.getTrainGroup());
                break;
        }
    }

    private void setFollowingCamera() {
        PosPoint posView = (PosPoint) myController.doEvent("GetPosPoint", target.getTrainPos());
       //System.err.println(posView.path_ID+" "+posView.d);
        /*if (posView.pos == null) {
            return;
        }*/
        if (following_type == Camera.FOLLOW_DRIVER ||
                following_type == Camera.FOLLOW_DESK){
                if(target.getTrainGroup().isLive())
                    target.getTrainGroup().detach();
        }else{
                if(!target.getTrainGroup().isLive())
                    ControlCenter.objRoot.addChild(target.getTrainGroup());
        }

        switch (following_type) {
            case Camera.FOLLOW_DRIVER:
                target.getDashboard().setCPVisualType(0);
                if (!target.isIsReversed()) {
                    posView.AngV += Math.PI;
                }
                ControlCenter.setView(
                        new Vector3d(posView.pos.x, posView.pos.y + 2.5f, posView.pos.z),
                        new Vector3d(0, posView.AngV - Math.PI / 2, -posView.AngH));
                break;

            case Camera.FOLLOW_DESK:
                target.getDashboard().setCPVisualType(3);
                if (!target.isIsReversed()) {
                    posView.AngV += Math.PI;
                }
                ControlCenter.setView(
                        new Vector3d(posView.pos.x+ 1 * Math.sin(posView.AngV + Math.PI / 4),
                        posView.pos.y + 2.5f, posView.pos.z+ 1* Math.cos(posView.AngV + Math.PI / 4)),
                        new Vector3d(0, posView.AngV - Math.PI / 2, -posView.AngH));
                break;

            case Camera.FOLLOW_CARRIAGE:
                target.getDashboard().setCPVisualType(2);
                posView=target.getTrainPos();
                
                if (!target.isIsReversed()) {
                    posView.d+=40;
                    posView = (PosPoint) myController.doEvent("GetPosPoint", posView);
                    posView.AngV += Math.PI;
                }else{
                    posView.d-=40;
                    posView = (PosPoint) myController.doEvent("GetPosPoint", posView);
                }
                ControlCenter.setView(
                        new Vector3d(posView.pos.x,// - 40 * Math.cos(posView.AngV),
                        posView.pos.y + 2.6f,
                        posView.pos.z),// - 40* Math.sin(posView.AngV)),
                        new Vector3d(0, posView.AngV - Math.PI / 2.5, -posView.AngH));
                break;

            case Camera.FOLLOW_OUTSIDE:
                target.getDashboard().setCPVisualType(2);
                if (!target.isIsReversed()) {
                    posView.AngV += Math.PI;
                }
                ControlCenter.setView(
                        new Vector3d(posView.pos.x + 20 * Math.sin(posView.AngV + Math.PI / 4),
                        posView.pos.y + 4f,
                        posView.pos.z + 4* Math.cos(posView.AngV + Math.PI / 4)),
                        new Vector3d(0, posView.AngV + Math.PI / 2, -posView.AngH));
                break;

            case Camera.FOLLOW_FIXED:
                target.getDashboard().setCPVisualType(2);
                if (!target.isIsReversed()) {
                    posView.d = ((int) (posView.d / 300)) * 300;
                } else {
                    posView.d = (((int) (posView.d / 300)) + 1) * 300;
                }
                posView = (PosPoint) myController.doEvent("GetPosPoint", posView);
                if (!target.isIsReversed()) {
                    posView.AngV += Math.PI;
                }
                ControlCenter.setView(
                        new Vector3d(posView.pos.x + 5 * Math.sin(posView.AngV + Math.PI / 4),
                        posView.pos.y + 4f,
                        posView.pos.z + 5 * Math.cos(posView.AngV + Math.PI / 4)),
                        new Vector3d(0, posView.AngV + Math.PI / 2, -posView.AngH));
                break;
        }
    }

    private void setDriverCamera() {
        target = (Train) myController.doEvent("GetTrain", null);
        if(!target.getTrainGroup().isLive())
            ControlCenter.objRoot.addChild(target.getTrainGroup());

         target.getDashboard().setCPVisualType(1);
        PosPoint posView = (PosPoint) myController.doEvent("GetPosPoint", target.getTrainPos());
        if (posView == null) {
            return;
        }
        if (target.isIsReversed()) {
            posView.AngV += Math.PI/2;
        }else{
            posView.AngV -= Math.PI/2;
        }
        
        if (target.getDoorLock()==Train.ALLOW_LEFT_DOOR_OPEN){
            ControlCenter.setView(
                    new Vector3d(posView.pos.x + 4 * Math.sin(posView.AngV + Math.PI / 4),
                    posView.pos.y + 2.9f,
                    posView.pos.z + 4 * Math.cos(posView.AngV + Math.PI / 4)),
                    new Vector3d(0, posView.AngV , 0));
        }else{
            ControlCenter.setView(
                    new Vector3d(posView.pos.x -4 * Math.sin(posView.AngV + Math.PI / 4),
                    posView.pos.y + 2.9f,
                    posView.pos.z - 4 * Math.cos(posView.AngV + Math.PI / 4)),
                    new Vector3d(0, posView.AngV , 0));
        }
    }

    public void setCustomizeCamera(Vector3d pos, Vector3d rot) {
        ControlCenter.setView(pos, rot);
    }

    public void setFollowing_type(int following_type) {
        //System.err.println(following_type);
        this.following_type = following_type;
    }

    public void setStatue(int statue) {
        this.statue = statue;
    }
}
